﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.RobotJog.Collision.CApRJRobotJogCollisionLogic
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using System;
using System.Collections.ObjectModel;
using System.Windows.Forms;
using Tecnomatix.Engineering;
using Tecnomatix.Engineering.Ui.WPF;


namespace DnProcessSimulateCommands.RobotJog.Collision;

internal class CApRJRobotJogCollisionLogic
{
  private const double TwicePI = 6.2831853071795862;
  private CApRJCollisionQueryMgr _collisionManager;
  private TxObjectList _listMovingObjects;
  private ITxLocatableObject _sourceObject;
  private bool _stopRunCollision;

  public CApRJRobotJogCollisionLogic(ITxLocatableObject sourceObject)
  {
    this._sourceObject = sourceObject;
  }

  private void AddAllDescendants(TxObjectList list)
  {
    ITxTypeFilter itxTypeFilter = (ITxTypeFilter) new TxTypeFilter(typeof (ITxObject));
    foreach (ITxObject itxObject in (Collection<ITxObject>) list)
    {
      if (!((Collection<ITxObject>) this._listMovingObjects).Contains(itxObject))
      {
        ((Collection<ITxObject>) this._listMovingObjects).Add(itxObject);
        if (itxObject is ITxLocatableObject)
          this.AddAllDescendants((itxObject as ITxLocatableObject).GetDirectAttachmentDescendants(itxTypeFilter));
        if (itxObject is ITxObjectCollection)
          this.AddAllDescendants((itxObject as ITxObjectCollection).GetDirectDescendants(itxTypeFilter));
      }
    }
  }

  private bool HasCollidingObjects(TxCollisionQueryResults listCollision)
  {
    foreach (TxCollisionState state in listCollision.States)
    {
      if (((Collection<ITxObject>) this._listMovingObjects).Contains(state.FirstObject) ^ ((Collection<ITxObject>) this._listMovingObjects).Contains(state.SecondObject))
        return true;
    }
    return false;
  }

  private bool MoveOneStep(
    TxPlacementCollisionControlRunCollisionEventArgs args)
  {
    args.RunCallBack((object) this);
    return args.HasMove;
  }

  private bool IsFullRotation(
    double start,
    TxPlacementCollisionControlRunCollisionEventArgs args)
  {
    return args.MoveOrRotateRunCollision == 2 && Math.Abs(args.Value - start) * TxApplication.Options.Units.AngularMultiplier > 2.0 * Math.PI;
  }

  public bool RunToCollision(
    TxPlacementCollisionControlRunCollisionEventArgs args,
    bool lockTCPF,
    bool enableRobotPlacement)
  {
    Application.DoEvents();
    this._stopRunCollision = false;
    bool RestartNow = true;
    bool flag = true;
    double start = args.Value;
    while (!this.HasCollision(RestartNow, lockTCPF, enableRobotPlacement))
    {
      flag = false;
      if (!this.MoveOneStep(args) || this.IsFullRotation(start, args))
        return false;
      Application.DoEvents();
      RestartNow = false;
      if (this._stopRunCollision)
        return false;
    }
    if (!flag)
    {
      if (args.LeftOrRightRunCollision == 1)
        args.LeftOrRightRunCollision = (TxPlacementCollisionControlRunCollisionEventArgs.LeftRightRunCollision) 2;
      else if (args.LeftOrRightRunCollision == 2)
        args.LeftOrRightRunCollision = (TxPlacementCollisionControlRunCollisionEventArgs.LeftRightRunCollision) 1;
      this.MoveOneStep(args);
    }
    return true;
  }

  public void StopRunToCollision() => this._stopRunCollision = true;

  private bool HasCollision(bool RestartNow, bool lockTCPF, bool enableRobotPlacement)
  {
    TxCollisionQueryResults listCollision;
    if (this._collisionManager == null | RestartNow)
    {
      this._listMovingObjects = new TxObjectList();
      if (this._sourceObject != null)
      {
        if (this._sourceObject is TxRobot)
        {
          TxRobot sourceObject = this._sourceObject as TxRobot;
          if (!lockTCPF)
          {
            ITxTypeFilter itxTypeFilter = (ITxTypeFilter) new TxTypeFilter(typeof (ITxObject));
            TxObjectList attachmentDescendants = sourceObject.Toolframe.GetDirectAttachmentDescendants(itxTypeFilter);
            ((Collection<ITxObject>) attachmentDescendants).Add((ITxObject) sourceObject);
            this.AddAllDescendants(attachmentDescendants);
          }
          else if (enableRobotPlacement)
            ((Collection<ITxObject>) this._listMovingObjects).Add((ITxObject) this._sourceObject);
        }
        else
        {
          TxObjectList list = new TxObjectList();
          ((Collection<ITxObject>) list).Add((ITxObject) this._sourceObject);
          this.AddAllDescendants(list);
        }
      }
      this._collisionManager = new CApRJCollisionQueryMgr();
      this._collisionManager.SelectedFilter = eFilterType.CollisionsOnly;
      listCollision = this._collisionManager.GetAllCollisionsQueryResults();
    }
    else
      listCollision = this._collisionManager.GetQueryResults();
    return listCollision.States.Count != 0 && (!RestartNow || this.HasCollidingObjects(listCollision));
  }
}
